/******************************************************************************************************
Copyright (C) 2015 Mestrelab Research S.L. All rights reserved.

This file is part of the Mnova scripting toolkit.

Authorized users of MNova Software may use this file freely, but this file is provided AS IS
with NO WARRANTY OF ANY KIND, INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS
FOR A PARTICULAR PURPOSE.
*******************************************************************************************************/

/*globals Application, qsTr, nmr, MnUi, mainWindow, SnrPeakCalculator, Peaks, MessageBox*/
/*jslint plusplus: true indent: 4*/

//////////START INTERACTIVE GUI IMPLEMENTATION/////////
function SnrPeakCalculator_Interactive() {
	'use strict';

	var spc, dialog, originalLimits, zoomChecked, oldPeaks, currentPeakPeackingMethod, aborted, logLevel = 1;

	SnrPeakCalculator_Interactive.getNoiseRegion = function (aOriginalLimits) {
		var showDialog, message, waitRes, noiseLimits;

		//Calculate in a loop the noise up to the user had selected a region which not be the whole specrum range
		noiseLimits = spc.getScaleLimits();
		if (noiseLimits === undefined || ((aOriginalLimits.fromX - aOriginalLimits.toX) === (noiseLimits.fromX - noiseLimits.toX))) {
			showDialog = true;
			message = "Signals-free region not defined. Please Select a signals-free region to calculate the noise and press <b>Continue</b>";
			while (showDialog) {
				waitRes = mainWindow.waitForInput(message, qsTr("SNR Peak Calculator"));
				if (waitRes) {
					noiseLimits = spc.getScaleLimits();
				} else {
					return false;
				}
				if (noiseLimits === undefined || ((aOriginalLimits.fromX - aOriginalLimits.toX) === (noiseLimits.fromX - noiseLimits.toX))) {
					message = qsTr("Signals-free region not defined. Please Select a signals-free region to calculate the noise and press <b>Continue</b>");
				} else {
					showDialog = false;
				}
			}
		}
		return noiseLimits;
	};

	SnrPeakCalculator_Interactive.getSignalRegion = function (aOriginalLimits) {
		var waitRes, signalLimits;

		//Calculate the noise region selected by user. If there isn't a selections it will be used the whole specrum range
		spc.zoom(aOriginalLimits);
		spc.update();
		mainWindow.activeDocument.update();
		waitRes = Application.mainWindow.waitForInput(qsTr("Zoom-in to the region of interest and press <b>Continue</b>"), qsTr("SNR Peak Calculator"));
		if (!waitRes) {
			mainWindow.doAction("drwModeSelect");
			return false;
		}
		signalLimits = spc.getScaleLimits();

		return signalLimits;
	};

	SnrPeakCalculator_Interactive.makeInteractiveManualPeakPicking = function () {
		var peaksInSpectrum, waitRes, showDialog, message;

		peaksInSpectrum = spc.peaks();

		if (peaksInSpectrum.count <= oldPeaks.count) {
			mainWindow.doAction("nmrManualPeakPicking");
			showDialog = true;
			message = qsTr("Select a range for manual peak picking and press <b>Continue</b>");

			while (showDialog) {
				waitRes = mainWindow.waitForInput(message, qsTr("SNR Peak Calculator"));
				if (!waitRes) {
					mainWindow.doAction("nmrManualPeakPicking");
					aborted = true;
					return;
				}
				peaksInSpectrum = spc.peaks();
				if (peaksInSpectrum.count === 0) {
					message = qsTr("Peaks not found in the given range. Please select a new range for manual peak picking and press <b>Continue</b>");
				} else {
					showDialog = false;
				}
			}
			mainWindow.doAction("nmrManualPeakPicking");
		}
	};

	SnrPeakCalculator_Interactive.calculateSNR = function () {
		var noiseLimits, signalLimits, parameters, snrPeakCalculatorInstance;

		try {
			//Get noise managing the exit
			noiseLimits = SnrPeakCalculator_Interactive.getNoiseRegion(originalLimits);
			if (!noiseLimits) {
				return;
			}

			//Get signal region
			signalLimits = SnrPeakCalculator_Interactive.getSignalRegion(originalLimits);
			if (!signalLimits) {
				return;
			}

			//Set parameters to engine by using an object sent pattern
			parameters = {};
			parameters.spectrum = spc;
			parameters.noiseStartX = noiseLimits.fromX;
			parameters.noiseEndX = noiseLimits.toX;
			parameters.noiseStartY = noiseLimits.fromY;
			parameters.noiseEndY = noiseLimits.toY;
			parameters.signalStartX = signalLimits.fromX;
			parameters.signalEndX = signalLimits.toX;
			parameters.signalStartY = signalLimits.fromY;
			parameters.signalEndY = signalLimits.toY;
			parameters.apply = spc.dimCount - 1; //0: 1D, 1: 2D, 2: 1D and 2D
			parameters.originalLimits = originalLimits;
			parameters.logLevel = logLevel;
			parameters.deleteOldPeaks = false;
			parameters.interactive = true;
			aborted = false;

			//Make peak picking by using the interactive and old way.
			SnrPeakCalculator_Interactive.makeInteractiveManualPeakPicking();

			//Create an instance to the engine sending the parameters to the constructor.
			if (!aborted) {
				snrPeakCalculatorInstance = new SnrPeakCalculator(parameters);
				if (snrPeakCalculatorInstance.status) {
					snrPeakCalculatorInstance.process();
				}

				//Show errors only
				if (snrPeakCalculatorInstance.logDetail !== undefined && snrPeakCalculatorInstance.logDetail !== "" && logLevel === 1) {
					MessageBox.critical(snrPeakCalculatorInstance.logDetail);
				}
			}
		} catch (err) {
			MessageBox.critical("Exception found during the SNR calculating process\n" + err);
		} finally {
			SnrPeakCalculator.setPeakPickingMethod(spc, currentPeakPeackingMethod);
		}
	};

	if (mainWindow.activeDocument.itemCount("NMR Spectrum") === 0) {
		MessageBox.warning("An NMR spectrum is required to perform the analysis");
		return;
	}
	spc = nmr.activeSpectrum();
	if (!spc.isValid()) {
		MessageBox.warning("The current spectrum is not valid");
		return;
	}

	SnrPeakCalculator.removeAllPeaks(spc);
	currentPeakPeackingMethod = SnrPeakCalculator.getPeakPickingMethod(spc);
	SnrPeakCalculator.setPeakPickingMethod(spc, "Standard");

	//Get the original limits and old peaks
	originalLimits = spc.getFullScaleLimits();
	oldPeaks = new Peaks(spc.peaks());

	if (!mainWindow.getObject("action_View_Zoom_in").checked) {
		zoomChecked = false;
		mainWindow.doAction("action_View_Zoom_in");
	} else {
		zoomChecked = true;
	}

	dialog = Application.loadUiFile('ricares:SnrPeakCalculator_Interactive.ui');

	dialog.widgets.btStop.clicked.connect(function () {
		if (!zoomChecked) {
			mainWindow.doAction("action_View_Zoom_in");
		}
		dialog.hide();
		SnrPeakCalculator.setPeakPickingMethod(spc, currentPeakPeackingMethod);
		return;
	});

	dialog.widgets.btContinue.clicked.connect(function () {
		dialog.hide();
		SnrPeakCalculator_Interactive.calculateSNR();
	});

	dialog.show();
}

if (this.MnUi && MnUi.scripts_nmr) {
	MnUi.scripts_nmr.scripts_nmr_SNRPeakCalculator = SnrPeakCalculator_Interactive;
}
